package cn.yitun.chat.yitunserverrunsingleboot.chat.common.app;

import cn.yitun.chat.yituncommonmessage.ExceptionEnum;
import cn.yitun.chat.yituncommonmessage.YitunException;
import cn.yitun.chat.yituncommonutil.YitunStringUtil;
import cn.yitun.chat.yitunservercommonlib.basebean.web.JwtUserDto;
import cn.yitun.chat.yitunservercommonlib.context.FilterContextHandler;
import cn.yitun.chat.yitunservercommonlib.util.JwtUtil;
import cn.yitun.chat.yitunservermanagecore.general.bridge.auth.manager.AuthManager;
import com.google.gson.Gson;
import io.jsonwebtoken.Claims;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;


/**
 * 描述：处理请求中携带jwtToken，将token信息封装供流程调用
 * 
 * @author yitun
 * @date 2020年06月19日
 * @since  1.1
 */
public class JwtUserResolver implements HandlerMethodArgumentResolver {

	@Resource
	AuthManager authManager;
	
	@Override
	public boolean supportsParameter(MethodParameter parameter) {
		return parameter.getParameterType() == JwtUserDto.class;
	}

	@Override
	public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
		HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);

		String token = request.getHeader("token");
		if (YitunStringUtil.isEmpty(token))
			throw new YitunException(ExceptionEnum.TOKEN_NULL);

		Long userId = authManager.getUserId(token);
		if (userId == null)
			throw new YitunException(ExceptionEnum.VERIFY_USER_NOT_FOUND);

		JwtUserDto jwtUserDto;
		try {
//            String decrypt = JwtUtil.decrypt(jwtToken);
			Claims claims = JwtUtil.parseJWT(token);
			String decrypt = claims.getSubject();
			jwtUserDto = new Gson().fromJson(decrypt, JwtUserDto.class);
		} catch (Exception e) {
			throw new YitunException(ExceptionEnum.DECRYPT_USER_INFO_ERROR);
		}

		//校验用户信息 比对
		checkTokenUserInfo(jwtUserDto);

		//localThread存储token
		FilterContextHandler.setJwtUserDto(jwtUserDto);

//		Class<?> clazz = parameter.getParameterType();
//		Object object = clazz.newInstance();
//		BeanWrapper beanWrapper = new BeanWrapperImpl(object);
//		beanWrapper.setPropertyValue("currentUserId", userId);
//		beanWrapper.setPropertyValue("token", token);
		return jwtUserDto;
	}

	/**
	 * 校验token
	 *
	 * @return
	 */
	private void checkTokenUserInfo(JwtUserDto jwtUserDTO) {
		// 如果缓存中命中失败,从数据库获取用户信息
		if (jwtUserDTO == null) {
			// 验证用户不存在
			throw new YitunException(ExceptionEnum.VERIFY_USER_NOT_FOUND);
		}
		if (YitunStringUtil.isEmpty(jwtUserDTO.getToken())) {
			// 如果用户当前没有token，说明没有登录或token过期
			throw new YitunException(ExceptionEnum.VERIFY_USER_NOT_FOUND);
		}
		if (jwtUserDTO.getUserId() == null ) {
			throw new YitunException(ExceptionEnum.VERIFY_USER_NOT_FOUND);
		}
		//TOKEN 到期
//        String userKey = RedisConstant.getUserKey(jwtUserDTO.getUserId(),jwtUserDTO.getCompanyId());
//        Object redisValue = redisManager.getObject(userKey);
//        if (redisValue == null) {
//            throw new YitunException(ExceptionEnum.TOKEN_EXPIRE);
//        } else {
//            //如果没有过期，则重置过期时间
//            redisManager.setObject (userKey, redisValue,
//                    RedisConstant.defalutExpireTime);
//        }
//        if (jwtUserDTO.getExpireTime() <= TimeUtil.getSystemInt()) {
//            throw new YitunException(ExceptionEnum.TOKEN_EXPIRE);
//        }
	}
}
